package com.settlement.system.service.impl;

import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.common.util.SecurityUtils;
import com.settlement.system.common.util.common.SystemUserUtil;
import com.settlement.system.mapper.BaseMapper;
import com.settlement.system.mapper.TblOrderAuditReportMapper;
import com.settlement.system.mapper.TblOrderCloseAccountLogMapper;
import com.settlement.system.mapper.TblOrderCloseAccountMapper;
import com.settlement.system.mapper.security.userdetails.SysUserDetails;
import com.settlement.system.model.entity.common.SystemUser;
import com.settlement.system.model.entity.common.TblOrderCloseAccount;
import com.settlement.system.model.entity.common.TblOrderCloseAccountLog;
import com.settlement.system.service.ITblOrderCloseAccountService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 订单稽核-关账表 服务实现类
 *
 * @author Ximi
 * @since 2020-09-17
 */
@Service
@Slf4j
public class TblOrderCloseAccountServiceImpl extends BaseServiceImpl implements ITblOrderCloseAccountService {

    @Resource
    private TblOrderCloseAccountMapper tblOrderCloseAccountMapper;

    @Resource
    private TblOrderAuditReportMapper tblOrderAuditReportMapper;

    @Resource
    private TblOrderCloseAccountLogMapper tblOrderCloseAccountLogMapper;

    @Override
    public BaseMapper init() {
        return tblOrderCloseAccountMapper;
    }

    @Override
    public Integer updateRealCloseAccountDate(TblOrderCloseAccount account) throws ServiceException {
        try {
            return tblOrderCloseAccountMapper.updateRealCloseAccountDate(account);
        } catch (Exception ex) {
            log.error("update real close account Date exception", ex);
            throw new ServiceException("update RealCloseAccountData exception", ex);
        }
    }

    @Override
    public TblOrderCloseAccount getById(String id) throws ServiceException {
        try {
            return tblOrderCloseAccountMapper.getById(id);
        } catch (Exception ex) {
            log.error("get orderCloseAccount data happen exception", ex);
            throw new ServiceException("get orderCloseAccount data happen exception", ex);
        }
    }

    @Override
    public TblOrderCloseAccount getByIds(List<String> ids) throws ServiceException {
        try {
            return tblOrderCloseAccountMapper.getByIds(ids);
        } catch (Exception ex) {
            log.error("get orderCloseAccount'data By ids happen exception", ex);
            throw new ServiceException("get orderCloseAccount'data By ids happen exception", ex);
        }
    }

    @Override
    public TblOrderCloseAccount getByThreeChannelNoAndShopAccount(String threeChannelNo, String shopAccount) throws ServiceException {
        try {
            return tblOrderCloseAccountMapper.getByThreeChannelNoAndShopAccount(threeChannelNo, shopAccount);
        } catch (Exception ex) {
            log.error("get orderCloseAccount'data By threeChannelNo and shopAccount happen exception", ex);
            throw new ServiceException("get orderCloseAccount'data By threeChannelNo and shopAccount happen exception", ex);
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void closeAccount(List<String> ids, Date realCloseAccountDate) throws ServiceException {

        SysUserDetails user = SecurityUtils.getUser();;
        for (String id : ids) {
            try {
                while (true) {

                    TblOrderCloseAccount current = tblOrderCloseAccountMapper.getById(id);
                    if (current == null) {
                        throw new ServiceException("数据被删除不能更新");
                    }

                    if (realCloseAccountDate.compareTo(current.getInitialDate()) < 0) {
                        throw new ServiceException("锁帐日期不能小于初始日期");
                    }

                    current.setRealCloseAccountDate(realCloseAccountDate);
                    if (current.getNeedRollbackAccountData().compareTo(realCloseAccountDate) > 0) {
                        current.setNeedRollbackAccountData(realCloseAccountDate);
                    }

                    if (user != null) {
                        current.setUpdateUser(user.getUsername());
                    }

                    if (tblOrderCloseAccountMapper.updateRealCloseAccountDate(current) > 0) {
                        tblOrderCloseAccountLogMapper.insert(initCloseAccountLog(current));
                        break;
                    }
                }
            } catch (ServiceException ex) {
                throw ex;
            } catch (Exception ex) {
                log.error("更新异常", ex);
                throw new ServiceException("系统异常", ex);
            }
        }
    }

    /**
     * 构造订单稽核锁帐对象
     *
     * @param current
     * @return
     */
    private TblOrderCloseAccountLog initCloseAccountLog(TblOrderCloseAccount current) {
        TblOrderCloseAccountLog tblOrderCloseAccountLog = new TblOrderCloseAccountLog();
        try {
            PropertyUtils.copyProperties(tblOrderCloseAccountLog, current);
        } catch (Exception e) {
            log.error("锁帐对象转换报错");
            return null;
        }
        tblOrderCloseAccountLog.setId(UUID.randomUUID().toString().replace("-", ""));
        tblOrderCloseAccountLog.setUpdateTime(new Date());
        return tblOrderCloseAccountLog;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void deleteCloseAccount(TblOrderCloseAccount account) throws ServiceException {
        try {
            tblOrderCloseAccountMapper.deleteById(account.getId());
            if (!StringUtils.isEmpty(account.getThreeLevelChannelNo())) {
                tblOrderAuditReportMapper.deleteByThreeChannelNo(account.getThreeLevelChannelNo());
            } else if (!StringUtils.isEmpty(account.getShopAccount())) {
                tblOrderAuditReportMapper.deleteByShopAccount(account.getShopAccount());
            }
        } catch (Exception ex) {
            throw new ServiceException("delete close account error", ex);
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public <ModelType> void save(List<ModelType> list) throws ServiceException {
        for (ModelType modelType : list) {
            saveClose((TblOrderCloseAccount) modelType);
        }
    }

    @Override
    public <ModelType> Integer insert(ModelType modelType) throws ServiceException {
        TblOrderCloseAccount closeAccount = (TblOrderCloseAccount) modelType;
        return saveClose(closeAccount);
    }

    private Integer saveClose(TblOrderCloseAccount closeAccount) throws ServiceException {
        try {
            return tblOrderCloseAccountMapper.insert(closeAccount);
        } catch (Exception ex) {
            if (ex.getCause() instanceof DuplicateKeyException || ex instanceof DuplicateKeyException) {
                String message = null;
                if (!StringUtils.isEmpty(closeAccount.getThreeLevelChannelNo())) {
                    message = "三级来源:" + closeAccount.getThreeLevelChannelNo() + "已经存在";
                } else {
                    message = "店铺账号:" + closeAccount.getShopAccount() + "已经存在";
                }
                throw new ServiceException(message);
            }
            throw new ServiceException("系统异常");
        }
    }
}
